#include "Camera.h"

Camera::Camera(CollisionManager * cm ) : IMovingSphere (cm)
{
	_speed = 0.4;
	_rotThrottle = 800.0;
	_fly = true;
	_horizontalAngle = 0.0;
	_verticalAngle = 0.0;
	_collisionSphereRadius = 1.0;
	_gravitationalPull = 0.04;
}

Vector3 Camera::getPosition()
{
	return _pos + _offset;
}

Vector3 Camera::getPos()
{
	return _pos;
}

float Camera::getRadius()
{
	return _collisionSphereRadius;
}

void Camera::setRadius(float r)
{
	_collisionSphereRadius = r;
}

Vector3 Camera::getOffset()
{
	return _offset;
}

void Camera::setOffset(Vector3 offs)
{
	_offset = offs;
}

Vector3 Camera::getDirection()
{
	Vector3 vec(cos(_horizontalAngle-GeoMath::DegToRad(90.0))*_speed ,-sin(_verticalAngle)*_speed,sin(_horizontalAngle-GeoMath::DegToRad(90.0))*_speed);
	return vec;
}

Vector3 Camera::getDir()
{
	return _dirDelta;
}

void Camera::setPosition(const Vector3& pos)
{
	_pos = pos;
}

float Camera::getHorizontalAngle()
{
	return _horizontalAngle;
}

float Camera::getVerticalAngle()
{
	return _verticalAngle;
}

void Camera::setMoveSpeed( float speed )
{
	_speed = speed;
}

float Camera::getMoveSpeed( )
{
	return _speed;
}

void Camera::setRotThrottle( float throttle )
{
	_rotThrottle = throttle;
}

float Camera::getRotThrottle( )
{
	return _rotThrottle;
}

void Camera::GO_FORWARD()
{
	Vector3 dir = getDirection();
	if( !_fly )// if fly mode deactivated dont add the y element
		dir.setY(0.0);

	_dirDelta = dir;
	_dirDelta.setY( _dirDelta.getY() - _gravitationalPull );// erdanziehung
	dir = GetMovement ();

	_pos = _pos + dir;
}

void Camera::GO_FORWARD_LEFT()
{
	Vector3 dir = getDirection();
	if( !_fly )// if fly mode deactivated dont add the y element
		dir.setY(0.0);

	dir = Matrix3::RotateY( GeoMath::DegToRad( 45.0 ) ) * dir;

	_dirDelta = dir;
	dir = GetMovement ();

	_pos = _pos + dir;
}

void Camera::GO_FORWARD_RIGHT()
{
	Vector3 dir = getDirection();
	if( !_fly )// if fly mode deactivated dont add the y element
		dir.setY(0.0);

	dir = Matrix3::RotateY( GeoMath::DegToRad( -45.0 ) ) * dir;

	_dirDelta = dir;
	dir = GetMovement ();

	_pos = _pos + dir;
}

void Camera::GO_BACKWARD()
{
	Vector3 dir = getDirection();
	if( !_fly )// if fly mode deactivated dont add the y element
		dir.setY(0.0);

	_dirDelta = (dir *(-1.0));
	dir = GetMovement ();

	_pos = _pos + dir;
}

void Camera::GO_BACKWARD_LEFT()
{
	Vector3 dir = getDirection();
	if( !_fly )// if fly mode deactivated dont add the y element
		dir.setY(0.0);

	dir = Matrix3::RotateY( GeoMath::DegToRad( -45.0 ) ) * dir;

	_dirDelta = (dir *(-1.0));
	dir = GetMovement ();

	_pos = _pos + dir;
}

void Camera::GO_BACKWARD_RIGHT()
{
	Vector3 dir = getDirection();
	if( !_fly )// if fly mode deactivated dont add the y element
		dir.setY(0.0);

	dir = Matrix3::RotateY(  GeoMath::DegToRad( 45.0 ) ) * dir;

	_dirDelta = (dir *(-1.0));
	dir = GetMovement ();

	_pos = _pos + dir;
}

void Camera::STRAFE_LEFT()
{
	Vector3 dir = getDirection();
	Vector2 ortho( dir.getX(), dir.getZ() );
	ortho = Matrix2::Rotate( GeoMath::DegToRad( -90.0 ) ) * ortho;

	dir = Vector3( ortho.getX(), 0.0, ortho.getY() );

	_dirDelta = dir;
	dir = GetMovement ();

	_pos = _pos + dir;
}

void Camera::STRAFE_RIGHT()
{
	Vector3 dir = getDirection();
	Vector2 ortho( dir.getX(), dir.getZ() );
	ortho = Matrix2::Rotate( GeoMath::DegToRad( 90.0 ) ) * ortho;

	dir = Vector3( ortho.getX(), 0.0, ortho.getY() );

	_dirDelta = dir;
	dir = GetMovement ();

	_pos = _pos + dir;
}

void Camera::ROT_LEFT(float faktor)
{
	//Move the Camera in Y Axis
	float xAngle = ((float)(faktor))/_rotThrottle;

	_horizontalAngle += xAngle;
	if( GeoMath::RadToDeg( _horizontalAngle ) >= 360.0 )
		_horizontalAngle -= GeoMath::DegToRad(360.0);

	//cout << "# "<<GeoMath::RadToDeg(_horizontalAngle)<<" #"<<endl;
}

void Camera::ROT_RIGHT(float faktor)
{
	//Move the Camera in Y Axis
	float xAngle = ((float)(faktor))/_rotThrottle;

	_horizontalAngle += xAngle;
	if( GeoMath::RadToDeg( _horizontalAngle ) >= 360.0 )
		_horizontalAngle -= GeoMath::DegToRad(360.0);

	//cout << "# "<<GeoMath::RadToDeg(_horizontalAngle)<<" #"<<endl;
}

void Camera::ROT_UP(float faktor)
{
	float yAngle = ((float)(faktor))/_rotThrottle;
	if( GeoMath::RadToDeg( _verticalAngle + yAngle ) < 75.0 )
		_verticalAngle += yAngle;

	//cout << "# "<<GeoMath::RadToDeg(_verticalAngle)<<" #"<<endl;
}

void Camera::ROT_DOWN(float faktor)
{
	float yAngle = ((float)(faktor))/_rotThrottle;
	if( GeoMath::RadToDeg( _verticalAngle + yAngle ) > -75.0 )
		_verticalAngle += yAngle;

	//cout << "# "<<GeoMath::RadToDeg(_verticalAngle)<<" #"<<endl;
}

bool Camera::isFlyMode()
{
	return _fly;
}

void Camera::setFlyMode(bool fly)
{
	_fly = fly;
}

void Camera::setHeight(float height)
{
	_pos.setY(height);
}

void Camera::RenderObject()
{
	glRotatef (GeoMath::RadToDeg(this->getVerticalAngle()), 1.0, 0.0, 0.0);  /* Rotation um die X-Z-Achse */
	glRotatef (GeoMath::RadToDeg(this->getHorizontalAngle()), 0.0, 1.0, 0.0);  /* Rotation um die Y-Achse */
	glTranslatef (-this->getPosition().getX(), -this->getPosition().getY() ,-this->getPosition().getZ());
}


